home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (c) 1993, George Byrkit
- Software Professionals Limited
- 1809 Saxon Street
- Ann Arbor, MI 48103
- (313)-663-1009
-
- ALL RIGHTS RESERVED
-
- THIS FILE MAY BE INCLUDED ROYALTY-FREE in any program as long as the
- above copyright notice also appears in the text of the program executable.
-
- I hereby certify that I did NOT examine the internals of the equivalent
- Windows (reg TM of MicroSoft) functions in order to create these
- approximately functionally equivalent routines.
-
- Differences are:
- I don't look for a windows installation directory. If you use the
- non-private functions, the file 'win.ini' is looked for in the CURRENT
- DIRECTORY
-
- filename: inifile.cpp
-
- purpose: emulate windows API functions to access the ini files
-
- instructions for building:
- compile:
- link:
- other:
-
- change log:
- When Version Who Why
- 01-jan-93 1.0 ghb created
- */
-
- /*
- PRAGMAS
- */
-
- /*
- INCLUDE FILES
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "inifile.h"
-
- /*
- LOCAL DEFINES AND MACROS
- */
-
- /*
- LOCAL STRUCTURES AND TYPEDEFS
- */
-
- /*
- FORWARD REFERENCES TO FUNCTIONS DEFINED IN THIS SOURCE FILE
- */
-
- /*
- EXTERN FUNCTION AND DATA REFERENCES
- */
-
- /*
- LOCAL DATA (MAY BE GLOBAL OR STATIC)
- */
- /*
- this string MUST be part of the executable file for the functions in
- this file to be used in a non-infringing way
- */
- static char *pCWN = "inifile code is Copyright (c) 1993, George Byrkit\n"
- "Software Professionals Limited\n"
- "1809 Saxon Street\n"
- "Ann Arbor, MI 48103\n"
- "(313)-663-1009\n"
- "ALL RIGHTS RESERVED\n";
-
- /*
- Note that appname and keyname are treated case-insensitively.
- */
-
- /*
- returns a pointer to the line that contains the desired string
-
- open for write opens a file from the beginning
- */
-
- /*
- basic finding function for reads.
-
- see ScanForCopy for use with writes
- */
- int ScanFor ( LPCSTR lpAppName, LPCSTR lpKeyName,
- LPSTR lpReturnedString, int nSize,
- FILE *pIniFile )
- {
- int appLen = strlen ( lpAppName );
- int keyLen = strlen ( lpKeyName );
- char *rc;
-
- // find application name, if present
- do {
- rc = fgets ( lpReturnedString, nSize, pIniFile );
- // check for error, possibly EOF.
- if ( rc != lpReturnedString ) {
- // didn't find the application. Return not found
- return 0;
- }
- } while ( lpReturnedString[0] != '['
- || strnicmp ( lpAppName, &lpReturnedString[1], appLen )
- || lpReturnedString[1+appLen] != ']' );
-
- // OK, we found the application section. Now look for the keyword
- do {
- rc = fgets ( lpReturnedString, nSize, pIniFile );
- // check for error, possibly EOF.
- if ( rc != lpReturnedString ) {
- // didn't find the application. Return not found
- return 0;
- }
- // at the end of an application. Obviously we didn't find the keyword
- if ( lpReturnedString[0] == '[' ) {
- // didn't find the keyword. Return not found
- return 0;
- }
- } while ( strnicmp ( lpKeyName, lpReturnedString, keyLen )
- || lpReturnedString[keyLen] != '=' );
-
- // OK, we found it, and it's in the current buffer. Return success.
- // Success is the nonzero index into the return string of where
- // the result (after the equal sign) is located
- return keyLen+1;
- }
-
- /*
- basic finding function for writes.
-
- see ScanFor for use with reads
- */
- InsertSection ( LPCSTR lpAppName, LPCSTR lpKeyName,
- LPCSTR lpValue, FILE *pFile )
- {
- return fprintf ( pFile, "[%s]\n%s=%s\n", lpAppName, lpKeyName, lpValue );
- }
-
- InsertKey ( LPCSTR lpKeyName, LPCSTR lpValue, FILE *pFile )
- {
- return fprintf ( pFile, "%s=%s\n", lpKeyName, lpValue );
- }
-
- /*
- return of zero means no more copy to do.
- */
- int ScanForCopyInsert ( LPCSTR lpAppName, LPCSTR lpKeyName,
- LPCSTR lpValue,
- FILE *pIniFile, FILE *pIniFileCopy )
- {
- int appLen = strlen ( lpAppName );
- int keyLen = strlen ( lpKeyName );
- char lpReturnedString [256];
- char *rc;
-
- // find application name, if present
- do {
- rc = fgets ( lpReturnedString, 256, pIniFile );
- // check for error, possibly EOF.
- if ( rc != lpReturnedString ) {
- // didn't find the application. Return not found
- InsertSection ( lpAppName, lpKeyName, lpValue, pIniFileCopy );
- return 0;
- }
- // copy to output
- fputs ( lpReturnedString, pIniFileCopy );
- } while ( lpReturnedString[0] != '['
- || strnicmp ( lpAppName, &lpReturnedString[1], appLen )
- || lpReturnedString[1+appLen] != ']' );
-
- // OK, we found the application section. Now look for the keyword
- do {
- rc = fgets ( lpReturnedString, 256, pIniFile );
- // check for error, possibly EOF.
- if ( rc != lpReturnedString ) {
- // didn't find the application. Return not found
- InsertKey ( lpKeyName, lpValue, pIniFileCopy );
- return 1;
- }
- // at the end of an application. Obviously we didn't find the keyword
- if ( lpReturnedString[0] == '[' ) {
- InsertKey ( lpKeyName, lpValue, pIniFileCopy );
- // copy the line in the buffer, that we just read, that starts
- // a new section
- fputs ( lpReturnedString, pIniFileCopy );
-
- // didn't find the keyword. Return not found
- return 1;
- }
- if ( !strnicmp ( lpKeyName, lpReturnedString, keyLen )
- && lpReturnedString[keyLen] == '=' ) {
- // this is the place
- break;
- }
- } while ( fputs ( lpReturnedString, pIniFileCopy ) != EOF );
-
- // OK, we found it, and it's in the current buffer. Replace what's after
- // the equal sign and up to any comment, with what's in the string we got
- // here to write in
- rc = strchr ( &lpReturnedString[keyLen+1], ';' );
- // we got a trailing comment. Now back up over whitespace
- if ( rc ) {
- while ( isspace(*(rc-1)) ) {
- rc--; // back up
- }
- // note that rc usually includes a newline character
- if ( !strchr ( rc, '\n' ) ) {
- // must provide a newline char, one wasn't there
- fprintf ( pIniFileCopy, "%s=%s%s\n", lpKeyName, lpValue, rc );
- }
- else {
- fprintf ( pIniFileCopy, "%s=%s%s", lpKeyName, lpValue, rc );
- }
- }
- else {
- fprintf ( pIniFileCopy, "%s=%s\n", lpKeyName, lpValue );
- }
-
- // indicate probably more to copy
- return 1;
- }
-
- UINT WINAPI GetPrivateProfileInt(LPCSTR lpAppName, LPCSTR lpKeyName,
- int nDefault,
- LPCSTR lpFileName)
- {
- char returnedString[256];
- UINT rc;
-
- FILE *pIniFile = fopen ( lpFileName, "rt" );
- if ( !pIniFile ) {
- return nDefault;
- }
-
- rc = ScanFor ( lpAppName, lpKeyName, returnedString, 256, pIniFile );
- if ( !rc ) {
- return nDefault;
- }
-
- // get integer value
- return (UINT) atol ( &returnedString[ rc ] );
- }
-
- int WINAPI GetPrivateProfileString(LPCSTR lpAppName, LPCSTR lpKeyName,
- LPCSTR lpDefault, LPSTR lpReturnedString, int nSize,
- LPCSTR lpFileName)
- {
- char returnedString[256];
- int rc;
- int i;
- int len;
- char *p;
-
- FILE *pIniFile = fopen ( lpFileName, "rt" );
- if ( !pIniFile ) {
- strcpy ( lpReturnedString, lpDefault );
- return strlen ( lpDefault );
- }
-
- rc = ScanFor ( lpAppName, lpKeyName, returnedString, 256, pIniFile );
- if ( !rc ) {
- strcpy ( lpReturnedString, lpDefault );
- return strlen ( lpDefault );
- }
-
- // get string. Copy out and back, to get rid of leading line info
- strcpy ( returnedString, &returnedString[ rc ] );
- // look for a double quote
- if ( returnedString[0] == '\"' ) {
- // find terminating quote
- p = strchr ( &returnedString[1], '\"' );
- p++;
- *p = '\0'; // string is terminated after end quote
- }
- else if ( NULL != ( p = strchr ( returnedString, ';' ) ) ) {
- // found a comment char
- // terminate string there. Trailing whitespace trim will still work.
- *p = '\0';
- }
-
- // trim off trailing whitespace
- len = strlen ( returnedString );
- for ( i = len-1; i > 0; i-- ) {
- if ( isspace(returnedString[i]) ) {
- returnedString[i] = '\0'; // trim it
- }
- else {
- break;
- }
- }
- strncpy ( lpReturnedString, returnedString, nSize - 1 );
- lpReturnedString[nSize] = '\0'; // force null termination
-
- return strlen ( lpReturnedString );
- }
-
- BOOL WINAPI WritePrivateProfileString(LPCSTR lpAppName, LPCSTR lpKeyName,
- LPCSTR lpValue,
- LPCSTR lpFileName)
- {
- char tmpFileName[256];
- char tmpFileName2[256];
- char buffer[256];
- int rc;
-
- FILE *pIniFileCopy;
- FILE *pIniFile = fopen ( lpFileName, "rt" );
-
- // if it doesn't exist, create it and insert this section
- if ( !pIniFile ) {
- pIniFile = fopen ( lpFileName, "wt" );
- if ( !pIniFile ) {
- return 0; // failure
- }
-
- InsertSection ( lpAppName, lpKeyName, lpValue, pIniFile );
- fclose ( pIniFile );
- return 0;
- }
-
- // get a temporary file name that is unique
- strcpy ( tmpFileName, lpFileName );
- tmpFileName[strlen ( tmpFileName )-1] = '$'; // turn last char into $
-
- pIniFileCopy = fopen ( tmpFileName, "wt" );
- // if can't open a temporary file, fail
- if ( !pIniFileCopy ) {
- rc = errno;
- fclose ( pIniFile );
- return 0;
- }
-
- rc = ScanForCopyInsert ( lpAppName, lpKeyName, lpValue,
- pIniFile, pIniFileCopy );
-
- if ( rc ) {
- while ( !feof ( pIniFile ) ) {
- if ( buffer != fgets ( buffer, sizeof ( buffer ) -1, pIniFile ) ) {
- if ( !feof ( pIniFile ) ) {
- rc = errno;
- fclose ( pIniFile );
- fclose ( pIniFileCopy );
- remove ( tmpFileName );
- return 0;
- }
- else {
- // it is end of file. All is copied. Swap files
- break;
- }
- }
- // while writing to the copy file, if an error is encountered
- if ( fputs ( buffer, pIniFileCopy ) == EOF ) {
- // error while writing
- rc = errno;
- fclose ( pIniFile );
- fclose ( pIniFileCopy );
- remove ( tmpFileName );
- return 0;
- }
- } // end while not eof
- }
-
- // close the files
- fclose ( pIniFile );
- fclose ( pIniFileCopy );
-
- // form the name of what to rename the current file to.
- strcpy ( tmpFileName2, lpFileName );
- tmpFileName2[strlen ( tmpFileName )-1] = '$'; // turn last char into $
- tmpFileName2[strlen ( tmpFileName )-2] = '$'; // also nextlast char into $
- rc = rename ( lpFileName, tmpFileName2 );
- if ( rc ) {
- // error on rename. can't do it. bail out
- rc = errno;
- remove ( tmpFileName );
- return 0;
- }
-
- rc = rename ( tmpFileName, lpFileName );
- if ( rc ) {
- // error on rename. can't do it. bail out
- rc = errno;
- // rename back original file. Pray for no error!
- rename ( tmpFileName2, lpFileName );
- remove ( tmpFileName ); // delete temp file
- return 0;
- }
-
- // all went OK. Now just delete the temp file that is the original file
- remove ( tmpFileName2 ); // delete temp file that is original file
-
- return 1;
- }
-
- UINT WINAPI GetProfileInt(LPCSTR lpAppName, LPCSTR lpKeyName,
- int nDefault)
- {
- return GetPrivateProfileInt (lpAppName, lpKeyName, nDefault, "win.ini" );
- }
-
- int WINAPI GetProfileString(LPCSTR lpAppName, LPCSTR lpKeyName,
- LPCSTR lpDefault, LPSTR lpReturnedString, int nSize)
- {
- return GetPrivateProfileString (lpAppName, lpKeyName, lpDefault,
- lpReturnedString, nSize, "win.ini" );
- }
-
- BOOL WINAPI WriteProfileString(LPCSTR lpAppName, LPCSTR lpKeyName,
- LPCSTR lpValue)
- {
- return WritePrivateProfileString (lpAppName, lpKeyName, lpValue, "win.ini");
- }
-
- #ifdef TEST
- main ()
- {
- char rv[256];
- GetPrivateProfileString ( "myapp2", "key2", "none", rv, 256, "myapp.ini" );
-
- printf ("Value of key %s in section %s is %s\n", "key2", "myapp2", rv );
- }
- #endif
-